﻿using JinYuan.Models;
using System;
using System.Collections.Generic;
using System.Linq;

namespace JinYuan.Helper
{
    public static class PLCAlarmParseHelper
    {
        /// <summary>
        /// 三菱将报警地址值转成报警List
        /// </summary>
        /// <param name="plcAddrSuffix">PLC地址值，如100</param>
        /// <param name="byteData">PLC读取出来的值</param>
        /// <param name="plcAddrPrefix">PLC地址类型,默认值R</param>
        /// <returns></returns>
        public static List<AlarmStatus> MelsecByte2Status(int plcAddrSuffix, byte[] byteData, char plcAddrPrefix = 'R')
        {
            var listAlarmStatus = new List<AlarmStatus>();
            // byte[]转为二进制字符串表示
            string strResult = "";
            for (int i = 0; i < byteData.Length; i++)
            {
                string strTemp = System.Convert.ToString(byteData[i], 2);
                strTemp = strTemp.PadLeft(8, '0').StrReverse();
                strResult += strTemp;
            }

            for (int i = 0; i < strResult.Length; i++)
            {
                var plcByte = i % 16;
                //如果是16的倍数地址+1
                if (plcByte % 16 == 0 && i != 0)
                {
                    plcAddrSuffix++;
                }
                //将地址和状态添加到结果集
                listAlarmStatus.Add(new AlarmStatus()
                {
                    PLCAdress = $"{plcAddrPrefix}{plcAddrSuffix}.{plcByte.ToString("X")}",
                    Status = strResult[i] == '1'
                });
                //if (strResult[i] == '1')
                //    Console.WriteLine($"{plcAddrPrefix}{plcAddrSuffix}.{plcByte.ToString("X")}:{strResult[i]}");
            }

            return listAlarmStatus;
        }


        /// <summary>
        /// 欧姆龙NX系列Ethernet/IP通讯时将报警地址值转成报警List  {直接读取标签地址/无需高低位互换}
        /// </summary>
        /// <param name="plcAddrSuffix">PLC地址值，如100</param>
        /// <param name="byteData">PLC读取出来的值</param>
        /// <param name="plcAddrPrefix">PLC地址类型,默认值R</param>
        /// <returns></returns>
        public static List<AlarmStatus> OmronEIPByte2Status(int plcAddrSuffix, List<byte> byteData, char plcAddrPrefix = 'W')
        {
            var listAlarmStatus = new List<AlarmStatus>();
            // byte[]转为二进制字符串表示
            string strResult = "";
            for (int i = 0; i < byteData.Count; i++)
            {
                string strTemp = System.Convert.ToString(byteData[i], 2);
                strTemp = strTemp.PadLeft(8, '0').StrReverse();
                strResult += strTemp;
            }

            for (int i = 0; i < strResult.Length; i++)
            {
                var plcByte = i % 16;
                //如果是16的倍数地址+1
                if (plcByte % 16 == 0 && i != 0)
                {
                    plcAddrSuffix++;
                }
                //将地址和状态添加到结果集
                listAlarmStatus.Add(new AlarmStatus()
                {
                    PLCAdress = $"{plcAddrPrefix}6100[{plcAddrSuffix}].B[{plcByte.ToString()}]",
                    Status = strResult[i] == '1'
                });

                //if (strResult[i] == '1')
                //    Console.WriteLine($"{plcAddrPrefix}{plcAddrSuffix}.{plcByte.ToString("X")}:{strResult[i]}");
            }

            return listAlarmStatus;
        }


        /// <summary>
        /// 欧姆龙FINS通讯读取EM数据寄存器是时将报警地址值转成报警List
        /// </summary>
        /// <param name="plcAddrSuffix">PLC地址值，如100</param>
        /// <param name="byteData">PLC读取出来的值</param>
        /// <param name="plcAddrPrefix">PLC地址类型,默认值W</param>
        /// <returns></returns>
        public static List<AlarmStatus> OmronFinsByte2Status(int plcAddrSuffix, byte[] byteData, char plcAddrPrefix = 'D')
        {
            var listAlarmStatus = new List<AlarmStatus>();
            // byte[]转为二进制字符串表示
            byte[] revBytes = SWAPbyte(byteData); //字节高低位互换
            string strResult = "";
            for (int i = 0; i < revBytes.Length; i++)
            {
                string strTemp = System.Convert.ToString(revBytes[i], 2);
                strTemp = strTemp.PadLeft(8, '0').StrReverse();
                strResult += strTemp;
            }

            for (int i = 0; i < strResult.Length; i++)
            {
                var plcByte = i % 16;
                //如果是16的倍数地址+1
                if (plcByte % 16 == 0 && i != 0)
                {
                    plcAddrSuffix++;
                }
                //将地址和状态添加到结果集
                listAlarmStatus.Add(new AlarmStatus()
                {
                    PLCAdress = $"{plcAddrPrefix}{plcAddrSuffix}.{plcByte.ToString()}",
                    Status = strResult[i] == '1'
                });
                //if (strResult[i] == '1')
                //    Console.WriteLine($"{plcAddrPrefix}{plcAddrSuffix}.{plcByte.ToString("X")}:{strResult[i]}");
            }

            return listAlarmStatus;

        }
        /// <summary>
        /// 欧姆龙FINS通讯读取W数据寄存器是时将报警地址值转成报警List
        /// </summary>
        /// <param name="plcAddrSuffix">PLC地址值，如100</param>
        /// <param name="byteData">PLC读取出来的值</param>
        /// <param name="plcAddrPrefix">PLC地址类型,默认值W</param>
        /// <returns></returns>
        //public static List<AlarmStatus> OmronByte2Status(int plcAddrSuffix, byte[] byteData, char plcAddrPrefix = 'W')
        //{
        //    var listAlarmStatus = new List<AlarmStatus>();

        //    var addrCount = byteData.Length / 2;
        //    // byte[]每个地址保存的都是bool值，只取双数index位
        //    for (int i = 0; i < addrCount; i++)
        //    {
        //        //将地址和状态添加到结果集
        //        listAlarmStatus.Add(new AlarmStatus()
        //        {
        //            PLCAdress = $"{plcAddrPrefix}{plcAddrSuffix + i}",
        //            Status = byteData[i * 2 + 1] == 1

        //        });
        //        //if (byteData[i * 2 + 1] == 1)
        //        //    Console.WriteLine($"原始数据 PLC地址:{plcAddrPrefix}{plcAddrSuffix + i} 报警值：{byteData[i * 2 + 1]}");
        //    }

        //    return listAlarmStatus;
        //}




        /// <summary>
        /// 字符串反转
        /// </summary>
        /// <param name="str">需要反转字符串.Reverse()</param>
        /// <returns></returns>
        public static string StrReverse(this string str)
        {
            return new string(str.Reverse().ToArray());
        }


        /// <summary>
        ///byte字节高低位互换
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static byte[] SWAPbyte(byte[] data)
        {
            byte[] data2 = new byte[data.Length];
            for (int i = 0; i < data.Length; i += 2)
            {
                data2[i] = data[i + 1];
                data2[i + 1] = data[i];
            }
            return data2;
        }
    }
}

